package store.lunangangster.engine.impl.repository;

import java.io.InputStream;
import store.lunangangster.engine.ProcessEngineConfiguration;
import store.lunangangster.engine.impl.Context;
import store.lunangangster.engine.impl.cmd.CommandExecutor;
import store.lunangangster.engine.impl.cmd.DeployCmd;
import store.lunangangster.engine.impl.entity.DeploymentEntity;
import store.lunangangster.engine.impl.entity.ResourceEntity;
import store.lunangangster.engine.impl.entity.mgr.DeploymentEntityManager;
import store.lunangangster.engine.impl.entity.mgr.ResourceEntityManager;
import store.lunangangster.engine.impl.util.IOUtil;
import store.lunangangster.engine.repository.Deployment;
import store.lunangangster.engine.repository.DeploymentBuilder;

public class DeploymentBuilderImpl implements DeploymentBuilder {

  protected ProcessEngineConfiguration processEngineConfiguration;
  protected DeploymentEntity deployment;
  protected transient DeploymentEntityManager deploymentEntityManager;
  protected transient ResourceEntityManager resourceEntityManager;

  public DeploymentBuilderImpl() {
    processEngineConfiguration = Context.getProcessEngineConfiguration();
    deploymentEntityManager = processEngineConfiguration.getDeploymentEntityManager();
    resourceEntityManager = processEngineConfiguration.getResourceEntityManager();
    deployment = deploymentEntityManager.create();
    deployment.setNew(true);
  }

  @Override
  public Deployment deploy() {
    CommandExecutor commandExecutor = processEngineConfiguration.getCommandExecutor();
    return commandExecutor.execute(new DeployCmd(this));
  }

  @Override
  public DeploymentBuilder addName(String name) {
    deployment.setName(name);
    return this;
  }

  @Override
  public DeploymentBuilder addClassPathResource(String classPath) {
    InputStream is = Thread.currentThread().getContextClassLoader()
        .getResourceAsStream(classPath);
    return addInputStreamResource(classPath, is);
  }

  @Override
  public DeploymentBuilder addInputStreamResource(String resourceName, InputStream is) {
    byte[] bytes = IOUtil.getBytes(is);
    ResourceEntity resource = resourceEntityManager.create();
    resource.setName(resourceName);
    resource.setBytes(bytes);
    deployment.addResource(resource);
    return this;
  }

  public DeploymentEntity getDeployment() {
    return deployment;
  }
}
